package org.dicr.gui.io;

import java.awt.*;
import java.io.*;

import javax.swing.*;
import javax.swing.text.*;

import org.dicr.event.*;
import org.dicr.gui.*;

/***********************************************************************************************************************
 * @author Igor A Tarasov me@dicr.dn.ua
 * @version 020917
 **********************************************************************************************************************/
public class DocumentIO {
	protected long maxFileSize = 100000;

	protected CustomFileFilter fileFilter = new CustomFileFilter();

	protected File docFile = null;

	/*******************************************************************************************************************
	 * Конструктор
	 ******************************************************************************************************************/
	public DocumentIO() {
		try {
			jbInit();
		} catch (Exception ex) {
			DicrExceptionHandler.handleException(ex, this);
		}
	}

	/*******************************************************************************************************************
	 * инициализация
	 ******************************************************************************************************************/
	private void jbInit() {
		this.fileFilter.addExt("DOC");
		this.fileFilter.addExt("HTM");
		this.fileFilter.addExt("HTML");
		this.fileFilter.addExt("TXT");
		this.fileFilter.addExt("RTF");
		this.fileFilter.setDescription("Файлы документов");
	}

	/*******************************************************************************************************************
	 * Возвращает максимальный размер загружаемого файла
	 ******************************************************************************************************************/
	public long getMaxFileSize() {
		return this.maxFileSize;
	}

	/*******************************************************************************************************************
	 * Устанавливает максимальный размер загружаемого файла
	 ******************************************************************************************************************/
	public void setMaxFileSize(long size) {
		if (size < 10) throw new IllegalArgumentException("Неверный параметр size=" + size);
		this.maxFileSize = size;
	}

	/*******************************************************************************************************************
	 * Возвращает файл текущего документа
	 ******************************************************************************************************************/
	public File getDocumentFile() {
		return this.docFile;
	}

	/*******************************************************************************************************************
	 * Устанавливает файл текущего документа
	 ******************************************************************************************************************/
	public void setDocumentFile(File theDocFile) {
		this.docFile = theDocFile;
	}

	/*******************************************************************************************************************
	 * Создает новый пустой документ и устанавливает его редактору
	 ******************************************************************************************************************/
	public void initDocument(JEditorPane editor) {
		if (editor == null) throw new IllegalArgumentException("null параметр editor");
		Document doc = editor.getEditorKit().createDefaultDocument();
		editor.setDocument(doc);
	}

	/*******************************************************************************************************************
	 * Загружает документ из потока ввода/вывода
	 ******************************************************************************************************************/
	public void loadDocument(InputStream in, JEditorPane editor) throws BadLocationException, IOException {
		if (in == null) throw new IllegalArgumentException("null параметр in");
		if (editor == null) throw new IllegalArgumentException("null параметр editor");
		initDocument(editor);
		Document doc = editor.getDocument();
		EditorKit kit = editor.getEditorKit();
		kit.read(in, doc, 0);
	}

	/*******************************************************************************************************************
	 * Загружает документ из указанного файла
	 ******************************************************************************************************************/
	public void loadDocument(File theDocFile, JEditorPane editor) throws IOException, BadLocationException, FileNotFoundException {
		if (theDocFile == null) throw new IllegalArgumentException("null параметр docFile");
		if (editor == null) throw new IllegalArgumentException("null параметр editor");
		if (theDocFile.length() > this.maxFileSize) throw new FileNotFoundException("Ошибка загрузки файла: "
		        + theDocFile.getName() + ".\nРазмер файла " + theDocFile.length() + " превышает максимальный - "
		        + this.maxFileSize + " байт");
		this.docFile = theDocFile;
		// пытаемся установить content-type
		String filename = theDocFile.getName();
		int index = filename.indexOf(".");
		if (index >= 0) {
			String ext = filename.substring(index + 1);
			String content = getContentTypeByExt(ext);
			if (content != null) editor.setContentType(content);
		}
		FileInputStream in = new FileInputStream(theDocFile);
		loadDocument(in, editor);
	}

	/*******************************************************************************************************************
	 * Выводит диалог загрузки документа из файла
	 ******************************************************************************************************************/
	public boolean loadDocument(Component parent, JEditorPane editor) throws FileNotFoundException, BadLocationException, IOException {
		boolean ret = false;
		JFileChooser fileChooser = new JFileChooser();
		fileChooser.setAcceptAllFileFilterUsed(false);
		fileChooser.setFileFilter(this.fileFilter);
		fileChooser.setDialogTitle("Загрузка документа из файла");
		if (this.docFile != null) fileChooser.setSelectedFile(this.docFile);
		if (fileChooser.showOpenDialog(parent) == JFileChooser.APPROVE_OPTION) {
			File file = fileChooser.getSelectedFile();
			if (file != null) {
				loadDocument(file, editor);
				ret = true;
			}
		}
		return ret;
	}

	/*******************************************************************************************************************
	 * Выводит документ в поток вывода
	 ******************************************************************************************************************/
	public void saveDocument(OutputStream ou, JEditorPane editor) throws BadLocationException, IOException {
		if (ou == null) throw new IllegalArgumentException("null параметр ou");
		if (editor == null) throw new IllegalArgumentException("null параметр editor");
		Document doc = editor.getDocument();
		EditorKit kit = editor.getEditorKit();
		kit.write(ou, doc, 0, doc.getLength());
		ou.flush();
	}

	/*******************************************************************************************************************
	 * Сохраняет документ в указанный файл
	 ******************************************************************************************************************/
	public void saveDocument(File docfile, JEditorPane editor) throws BadLocationException, IOException {
		if (docfile == null) throw new IllegalArgumentException("null параметр docfile");
		if (editor == null) throw new IllegalArgumentException("null параметр editor");
		File _file = docfile;
		// дабывим расширение если файл без расширения
		String filename = _file.getName();
		int index = filename.indexOf(".");
		if (index < 0) _file = new File(filename + "." + getExtByContentType(editor.getContentType()));
		this.docFile = _file;
		OutputStream ou = new FileOutputStream(_file);
		saveDocument(ou, editor);
	}

	/*******************************************************************************************************************
	 * Сохранение документа в файл
	 ******************************************************************************************************************/
	public boolean saveDocument(JEditorPane editor, Component parent) throws BadLocationException, IOException {
		boolean ret = false;
		if (editor == null) throw new IllegalArgumentException("null параметр editor");
		JFileChooser fileChooser = new JFileChooser();
		fileChooser.setAcceptAllFileFilterUsed(false);
		fileChooser.setFileFilter(this.fileFilter);
		fileChooser.setDialogTitle("Сохранение документа в файл");
		if (this.docFile != null) fileChooser.setSelectedFile(this.docFile);
		while (true) {
			if (fileChooser.showSaveDialog(parent) != JFileChooser.APPROVE_OPTION) break;
			File file = fileChooser.getSelectedFile();
			if (file == null) break;
			if (file.getName().lastIndexOf(".") == -1) file = new File(file.getPath() + ".doc");
			if (file.exists()
			        && JOptionPane.showConfirmDialog(parent, "Файл " + file.getName()
			                + " уже существует - переписать поверху ?", "Запись изображения в файл",
			                JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE) != JOptionPane.YES_OPTION) continue;
			saveDocument(file, editor);
			ret = true;
			break;
		}
		return ret;
	}

	/*******************************************************************************************************************
	 * Возвращает расширение файла по content-type
	 ******************************************************************************************************************/
	public static String getExtByContentType(String contentType) {
		String ext = null;
		if (contentType.equals("text/html")) ext = "html";
		else if (contentType.equals("text/rtf")) ext = "rtf";
		else ext = "txt";
		return ext;
	}

	/*******************************************************************************************************************
	 * Возвращает текстовый content-type по расширению
	 * 
	 * @param ext расширение файла
	 * @return строку текстового content-type
	 ******************************************************************************************************************/
	public static String getContentTypeByExt(String ext) {
		String contentType = null;
		if (ext.equals("rtf")) contentType = "text/rtf";
		else if (ext.startsWith("htm")) contentType = "text/html";
		else contentType = "text/plain";
		return contentType;
	}
}
